<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body></body>
  <script>
    /*
               class类
       1 constructor
       2 属性
       3 方法
            原型关系
        每个class都有显示原型prototype
        每个实例都有隐式原型__proto__
        实例的__proto__指向该构造函数的显示原型
    */
    console.log(
      Object.__proto__ === Function.prototype,
      "Object.__proto__ === Function.prototype"
    );
    console.log(
      Function.__proto__ === Function.prototype,
      "Function.__proto__ === Object.prototype"
    );
    console.log(
      Function.prototype.__proto__ === Object.prototype,
      "Function.prototype.__proto__ === Object.prototype"
    );
    console.log(
      Object.prototype.__proto__ === null,
      "Object.prototype.__proto__ === null"
    );

    class Student {
      constructor(name, age, gender) {
        this.name = name;
        this.age = age;
        this.gender = gender;
      }
      xx = "sex"; // 实例属性
      ab = "ab";
      sayHi() {
        console.log(
          `我是学生，我叫${this.name}，今年${this.age}岁，性别${this.gender}`
        );
      }
      static skill() {
        console.log("我是一个学生，我擅长写作");
      }
    }
    Student.prototype.yy = "123yy";
    console.log(typeof Student, "typeof Student");
    let xialuo = new Student("夏洛克", 18, "男");
    console.log(xialuo.__proto__ === Student.prototype, "xialuo");
    xialuo.sayHi();
    Student.skill();
    let xiaowang = new Student("夏王", 17, "女");
    console.log(xiaowang.__proto__, "xiaowang");
    xiaowang.sayHi();
    /*
        继承
    1。extends关键字
    2。super关键字
    3.扩展或重写方法
    */
    Object.prototype.p = 123666;
    class Teacher extends Student {
      constructor(name, age, gender, skill) {
        super(name, age, gender); //继承的属性
        this.skill = skill; //新增的属性
      }
      sayHi() {
        console.log(
          "我是老师，我叫" +
            this.name +
            "，今年" +
            this.age +
            "岁，性别" +
            this.gender
        );
      }
      ss = "ss";

      /* 重写父类的方法 */
      static skill() {
        console.log("我是一个老师，我擅长教学");
      }
    }
    let t1 = new Teacher("老师1", 30, "男", "教数学");

    console.log(t1, "t111"); //Teacher {xx: 'sex', ab: 'ab', name: '老师1', age: 30, gender: '男', …}'
    console.log(t1.__proto__ === Teacher.prototype);
    console.log(t1.__proto__.__proto__ === Student.prototype);
    console.log(t1.__proto__.__proto__.__proto__ === Object.prototype);
    console.log(t1.__proto__.__proto__.__proto__.__proto__ === null);
    // for (let key in t1) {
    //   if (t1.hasOwnProperty(key)) {
    //     console.log(key, t1[key], "自己的属性");
    //   }
    // }

    console.log(
      t1.__proto__ === Teacher.prototype,
      "t1.__proto__ === Teacher.prototype"
    ); /*实例的隐式原型指向该构造函数的显示原型  */
    console.log(t1 instanceof Student, "t1 instanceof Student ");
    console.log(t1 instanceof Teacher, "t1 instanceof Teacher");
    console.log(
      t1.__proto__.__proto__ === Student.prototype,
      "t1.__proto__.__proto__ === Student.prototype"
    ); //true  t1实例的隐式原型指向该构造函数的显示原型， 又因Teacher继承了Student的属性和方法，所以Teacher的隐式原型指向了Student的显示原型
    // t1.sayHi();
    // Teacher.skill();

    /*
        instanceof 前者是不是后者的实例
    */
    // console.log(t1 instanceof Student); // true
    // console.log(t1 instanceof Teacher); // true
    // console.log(t1 instanceof Object); // true
    // let fn1 = function () {};
    // console.log(fn1 instanceof Object); // true
    // console.log([] instanceof Object);
    // console.log({} instanceof Object);
    // console.log([] instanceof Array);
    class P {
      constructor(name, age) {
        this.name = name;
        this.name = age;
      }
    }
    class D extends P {

      constructor(name, age) {

        super(name, age);
      }
    }
    let d1 = new D("d1", 18);
    console.log(d1);
  </script>
</html>
